package de.drkarl.simtiere;

import java.util.LinkedList;

import de.drkarl.charakters.Adler;
import de.drkarl.charakters.Animal;
import de.drkarl.charakters.Beute;
import de.drkarl.charakters.CharakterFaktory;
import de.drkarl.charakters.Hase;
import de.drkarl.charakters.Jaeger;
import de.drkarl.charakters.Maus;
import de.drkarl.charakters.Wolf;
import de.drkarl.interfaces.Observable;
import de.drkarl.verhalten.Position;
import de.drkarl.verhalten.MausVerteidigung;

public class Spielfeld implements Observable{
	public int xSize;
	public int ySize;
	public char schachbrett [][];
	CharakterFaktory charakterFaktory;
	
	LinkedList<Beute> beute;
	LinkedList<Jaeger> jaeger;
	LinkedList<Animal> animals;
	
	
	
	
	public Spielfeld(int xSize, int ySize) {
		super();
		this.xSize = xSize;
		this.ySize = ySize;
		schachbrett = new char [xSize][ySize];
		beute = new LinkedList<Beute>();
		jaeger = new LinkedList<Jaeger>();
		animals = new LinkedList<Animal>();
		charakterFaktory =  new CharakterFaktory(this);
	}

	public LinkedList<Beute> getBeute() {
		return beute;
	}

	public void setBeute(LinkedList<Beute> beute) {
		this.beute = beute;
	}
	
	public void addBeute(Beute beute){
		boolean saveToAdd = false;
		for (Animal animalInList : this.animals) {
				saveToAdd = true;
			if(animalInList.xPosition == beute.xPosition && animalInList.yPosition == beute.yPosition){
				System.out.println("Feld bereits besetzt.. modifiziere felddaten");
				if(beute.xPosition+1 < this.xSize){
					beute.xPosition = beute.xPosition +1;
				}else if (beute.yPosition+1 < this.ySize){
					beute.yPosition = beute.yPosition+1;
				}else if(beute.xPosition-1 > 0){
					beute.xPosition = beute.xPosition -1;
				}else if(beute.yPosition-1 > this.ySize){
					beute.yPosition = beute.yPosition-1;
				}else{
					System.out.println("Schachbrett ist voll..");
					break;
				}
				saveToAdd = false;
			}
		}
		this.getBeute().addLast(beute);
		this.getAnimals().addLast(beute);
	}

	public LinkedList<Jaeger> getJaeger() {
		return jaeger;
	}

	public void setJaeger(LinkedList<Jaeger> jaeger) {
		this.jaeger = jaeger;
	}
	
	boolean feldIstBesetzt(int x, int y){
		for (Jaeger jaeger : this.jaeger) {
			if(jaeger.getxPosition()==x && jaeger.getyPosition()==y){
				return true;
			}
		}
		for (Beute beute : this.beute) {
			if(beute.getxPosition()==x&&beute.getyPosition()==y){
				return true;
			}
		}
		return false;
	}
	
	public void kollisionskontrolle(){
		LinkedList<Animal> l= new LinkedList<Animal>();
		for (Animal outerAnimal : animals) {
			for (Animal innerAnimal : animals) {
				if(outerAnimal!=innerAnimal&& outerAnimal.xPosition==innerAnimal.xPosition&&outerAnimal.yPosition==innerAnimal.yPosition){
					if(outerAnimal instanceof Beute && innerAnimal instanceof Jaeger){
						l.addLast(outerAnimal);
					}
				}
			}
		}
		for (Animal animal : l) {
			deleteAnimal(animal);
		}
	}
	
	public void deleteAnimal(Animal animal){
		for (int i = 0; i < animals.size(); i++) {
			if(animal == animals.get(i)){
				animals.remove(i);
			}
		}
		for (int i = 0; i < beute.size(); i++) {
			if(animal == beute.get(i)){
				beute.remove(i);
			}
		}
		for (int i = 0; i < jaeger.size(); i++) {
			if(animal == jaeger.get(i)){
				jaeger.remove(i);
			}
		}
	}
	
	public void addJaeger(Jaeger jaeger){
		boolean saveToAdd = false;
		while(!saveToAdd){
			saveToAdd = true;
			for (Animal animalInList : this.animals) { 
				if(animalInList.xPosition == jaeger.xPosition && animalInList.yPosition == jaeger.yPosition){
					System.out.println("Feld bereits besetzt.. modifiziere felddaten");
					if(jaeger.xPosition+1 < this.xSize){
						jaeger.xPosition = jaeger.xPosition +1;
					}else if (jaeger.yPosition+1 < this.ySize){
						jaeger.yPosition = jaeger.yPosition+1;
					}else if(jaeger.xPosition-1 > 0){
						jaeger.xPosition = jaeger.xPosition -1;
					}else if(jaeger.yPosition-1 > this.ySize){
						jaeger.yPosition = jaeger.yPosition-1;
					}else{
						System.out.println("Schachbrett ist voll..");
						break;
					}
					saveToAdd = false;
				}
			}
		}
		this.getJaeger().addLast(jaeger);
		this.getAnimals().addLast(jaeger);
	}


	public LinkedList<Animal> getAnimals() {
		return animals;
	}

	public void setAnimals(LinkedList<Animal> animals) {
		this.animals = animals;
	}

	public String toString(){
		StringBuilder sb = new StringBuilder();
		for (int y = 0; y <	this.ySize; y++) {
			for (int x = 0; x < this.xSize; x++) {
				boolean animalAddet=false;
				for (Beute beute : this.beute) {
					if(beute.xPosition == x && beute.yPosition  == y){
						sb.append(beute.getBezeichnung()+"|");
						animalAddet=true;
					}
				}
				for (Jaeger jaeger : this.jaeger) {
					if(jaeger.xPosition==x && jaeger.yPosition == y){
						sb.append(jaeger.getBezeichnung()+"|");
						animalAddet=true;
					}
				}
				if(!animalAddet){
					sb.append("_|");
				}
			}
			sb.append("\n");
		}
		return sb.toString();
	}
	
	public void newRound(){
			notifyObservers();
	}

	
	public void notifyObservers() {
		
		for (Jaeger jaeger : this.jaeger) {
			jaeger.updatePosition();
		}
		kollisionskontrolle();
		for (Beute beute : this.beute) {
			beute.updatePosition();
		}
	}
	
	public void startGame(){
		Wolf W = (Wolf)charakterFaktory.getAnimal("Wolf");
		Adler A = (Adler)charakterFaktory.getAnimal("Adler");
		Maus m = (Maus) charakterFaktory.getAnimal("Maus");
		Hase h = (Hase) charakterFaktory.getAnimal("Hase");
		this.addBeute(h);
		this.addBeute(m);
		this.addJaeger(W);
		this.addJaeger(A);
		System.out.println(toString());
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
		}
		while(true){
			newRound();
			kollisionskontrolle();
			System.out.println(toString());
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
			}
			
		}
		
	}

	public static void main(String[] args) {
		Spielfeld s = new Spielfeld(12, 12);
		s.startGame();
		
	
	}

	
		
		
	}

	



	





	

